/**
 ******************************************************************************
 * 文件名          : bsp_can_core.c
 * 创建时间        : 2025.11.10
 * 作者            : Dayan
 ******************************************************************************
 *1. can 接口 核心入口模块
 * 2.本代码包含大量中文注释，请以UTF-8编码格式打开
 * 3.本代码最终解释权归哈尔滨工业大学（深圳）南工骁鹰战队Critical HIT所有
 *
 * Copyright (c) 哈尔滨工业大学（深圳）南工骁鹰战队Critical HIT 版权所有
 ******************************************************************************
 * 说明：
 ******************************************************************************
 */

#include "bsp_can_core.h"
#include <string.h>

// 静态变量
static CAN_HandleTypeDef *hcan_ptr = NULL;
static bsp_can_msg_t tx_queue[CAN_TX_QUEUE_SIZE];   // 发送队列
static bsp_can_msg_t rx_queue[CAN_RX_QUEUE_SIZE];   // 接收队列

static volatile uint8_t tx_head = 0, tx_tail = 0, tx_count = 0;  // 添加volatile
static volatile uint8_t rx_head = 0, rx_tail = 0, rx_count = 0;  // 添加volatile
static uint8_t filter_count = 0;
static bool initialized = false;



/**
 * @brief 初始化CAN驱动
 */
uint8_t BSP_CAN_Init(CAN_HandleTypeDef *hcan)
{
    // 初始化CAN核心
    if (bsp_can_core_init(hcan) != 0) {
        return 1;
    }
    
    // 初始化电机模块
    if (bsp_can_motor_init() != 0) {
        return 2;
    }
    
    return 0;
}

/**
 * @brief 主处理函数
 */
void BSP_CAN_Loop(void)
{
    // 处理CAN核心功能（发送队列）
    bsp_can_core_process();
    
    // 处理电机数据
    bsp_can_motor_process();
}

/**
 * @brief 初始化CAN核心
 */
uint8_t bsp_can_core_init(CAN_HandleTypeDef *hcan)
{
    if (hcan == NULL) {
        return 1;
    }
    
    hcan_ptr = hcan;
    
    // 清零队列（分开赋值，提高可读性）
    tx_head = 0;
    tx_tail = 0; 
    tx_count = 0;
    rx_head = 0;
    rx_tail = 0;
    rx_count = 0;
    filter_count = 0;
    
    // 配置CAN过滤器（基础配置，接收所有消息）
    CAN_FilterTypeDef filter_config = {
        .FilterIdHigh = 0x0000,
        .FilterIdLow = 0x0000,
        .FilterMaskIdHigh = 0x0000, 
        .FilterMaskIdLow = 0x0000,
        .FilterFIFOAssignment = CAN_RX_FIFO0,
        .FilterBank = 0,
        .FilterMode = CAN_FILTERMODE_IDMASK,
        .FilterScale = CAN_FILTERSCALE_32BIT,
        .FilterActivation = ENABLE
    };
    
    if (HAL_CAN_ConfigFilter(hcan_ptr, &filter_config) != HAL_OK) {
        return 3;
    }
    
    // 启动CAN
    if (HAL_CAN_Start(hcan_ptr) != HAL_OK) {
        return 2;
    }
    
    // 使能接收中断
    if (HAL_CAN_ActivateNotification(hcan_ptr, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
        return 4;
    }
    
    initialized = true;
    return 0;
}

/**
 * @brief 反初始化
 */
void bsp_can_core_deinit(void)
{
    if (!initialized) {
        return;
    }
    
    // 禁用中断
    HAL_CAN_DeactivateNotification(hcan_ptr, CAN_IT_RX_FIFO0_MSG_PENDING);
    
    // 停止CAN
    HAL_CAN_Stop(hcan_ptr);
    
    // 重置状态
    tx_head = tx_tail = tx_count = 0;
    rx_head = rx_tail = rx_count = 0;
    filter_count = 0;
    initialized = false;
}

/**
 * @brief 添加CAN过滤器
 */
uint8_t bsp_can_add_filter(uint16_t id, uint16_t mask)
{
    if (!initialized || filter_count >= CAN_MAX_FILTERS) {
        return 1;
    }
    
    CAN_FilterTypeDef filter_config = {
        .FilterIdHigh = (id << 5),
        .FilterIdLow = 0,
        .FilterMaskIdHigh = (mask << 5),
        .FilterMaskIdLow = 0,
        .FilterFIFOAssignment = CAN_RX_FIFO0,
        .FilterBank = filter_count,
        .FilterMode = CAN_FILTERMODE_IDMASK,
        .FilterScale = CAN_FILTERSCALE_16BIT,
        .FilterActivation = ENABLE
    };
    
    if (HAL_CAN_ConfigFilter(hcan_ptr, &filter_config) != HAL_OK) {
        return 2;
    }
    
    filter_count++;
    return 0;
}

/**
 * @brief 发送CAN消息
 */
uint8_t bsp_can_send(uint16_t id, const uint8_t *data, uint8_t len)
{
    if (!initialized) {
        return 1;
    }
    
    if (len > 8) {
        return 3;  // 数据长度错误
    }
    
    if (tx_count >= CAN_TX_QUEUE_SIZE) {
        return 2;  // 队列满
    }
    
    bsp_can_msg_t *msg = &tx_queue[tx_head];
    msg->id = id;
    msg->length = len;
    msg->timestamp = HAL_GetTick();
    
    if (data != NULL) {
        memcpy(msg->data, data, len);
    } else {
        memset(msg->data, 0, len);  // 数据为空时清零
    }
    
    // 原子操作更新队列（简单场景下，中断不会修改tx_head）
    tx_head = (tx_head + 1) % CAN_TX_QUEUE_SIZE;
    tx_count++;
    
    return 0;
}

/**
 * @brief 处理发送队列
 */
void bsp_can_core_process(void)
{
    if (!initialized) {
        return;
    }
    
    // 处理发送队列
    while (tx_count > 0 && HAL_CAN_GetTxMailboxesFreeLevel(hcan_ptr) > 0) {
        bsp_can_msg_t *msg = &tx_queue[tx_tail];
        
        CAN_TxHeaderTypeDef tx_header = {
            .StdId = msg->id,
            .ExtId = 0,
            .IDE = CAN_ID_STD,
            .RTR = CAN_RTR_DATA,
            .DLC = msg->length,
            .TransmitGlobalTime = DISABLE
        };
        
        uint32_t mailbox;
        HAL_StatusTypeDef result = HAL_CAN_AddTxMessage(hcan_ptr, &tx_header, 
                                                       msg->data, &mailbox);
        
        if (result == HAL_OK) {
            // 发送成功，从队列移除
            tx_tail = (tx_tail + 1) % CAN_TX_QUEUE_SIZE;
            tx_count--;
        } else {
            // 发送失败，跳出循环等待下次重试
            break;
        }
    }
}

/**
 * @brief 接收消息
 */
uint8_t bsp_can_receive(bsp_can_msg_t *msg)
{
    if (!initialized || msg == NULL) {
        return 1;
    }
    
    if (rx_count == 0) {
        return 2;  // 无消息
    }
    
    // 复制消息数据
    *msg = rx_queue[rx_tail];
    
    // 更新队列（简单场景下，中断不会修改rx_tail）
    rx_tail = (rx_tail + 1) % CAN_RX_QUEUE_SIZE;
    rx_count--;
    
    return 0;
}

/**
 * @brief 获取接收消息数量
 */
uint8_t bsp_can_available(void)
{
    return rx_count;
}

/**
 * @brief 清空接收队列
 */
void bsp_can_clear_rx_queue(void)
{
    rx_head = 0;
    rx_tail = 0;
    rx_count = 0;
}

/**
 * @brief 接收中断回调
 */
void bsp_can_rx_callback(void)
{
    if (!initialized) {
        return;
    }
    
    CAN_RxHeaderTypeDef rx_header;
    uint8_t data[8];
    uint32_t current_timestamp = HAL_GetTick();
    
    while (HAL_CAN_GetRxFifoFillLevel(hcan_ptr, CAN_RX_FIFO0) > 0) {
        if (HAL_CAN_GetRxMessage(hcan_ptr, CAN_RX_FIFO0, &rx_header, data) != HAL_OK) {
            continue;  // 读取失败，继续处理下一条消息
        }
        
        // 检查队列是否已满
        if (rx_count >= CAN_RX_QUEUE_SIZE) {
            return;  // 队列满，直接返回
        }
        
        // 只处理标准帧
        if (rx_header.IDE != CAN_ID_STD) {
            continue;
        }
        
        // 存储消息到队列
        bsp_can_msg_t *msg = &rx_queue[rx_head];
        msg->id = rx_header.StdId;
        msg->length = rx_header.DLC;
        msg->timestamp = current_timestamp;
        
        // 安全的数据拷贝
        uint8_t copy_length = (rx_header.DLC <= 8) ? rx_header.DLC : 8;
        if (copy_length > 0) {
            memcpy(msg->data, data, copy_length);
        }
        
        // 填充剩余数据区域（可选）
        if (copy_length < 8) {
            memset(&msg->data[copy_length], 0, 8 - copy_length);
        }
        
        // 更新队列指针和计数
        rx_head = (rx_head + 1) % CAN_RX_QUEUE_SIZE;
        rx_count++;
    }
}